<template>
  <div
    v-if="!initializing"
    class="vc-component"
    :style="visual.parseStyle(currNode.currStyle)"
  >
    <el-upload
      action=""
      :class="['cc-affix', {'is-disabled': inputDisabled}]"
      :disabled="inputDisabled"
      :multiple=true
      :http-request="handleUpload"
      :file-list="fileList"
      :show-file-list=false
      :before-upload="handleBeforeUpload"
    >
      <template #trigger>
        <el-button
          v-if="inputDisabled !== true"
          style="margin-right: 10px;"
          type="success"
        >
          <cc-icon
            iconId="018ece4f70fcf0627f81"
            size="18"
            style="margin-right: 5px"
          />点击上传
        </el-button>
      </template>
      <el-form :disabled="false">
        <el-button
          v-if="affixId != null && affixId !== '' && fileList.length > 1"
          :loading="downloading"
          @click.stop.prevent="downloadPack()"
          :disabled="false"
          type="primary"
        >
          <cc-icon
            iconId="018ece4f749ec5911772"
            size="18"
            style="margin-right: 5px"
          />打包下载
        </el-button>
      </el-form>
    </el-upload>

    <el-image-viewer
      v-if="showViewer"
      :z-index="5000"
      :url-list="[imageUrl]"
      hide-on-click-modal
      @close="() => { showViewer = false; }"
      teleported
    />

    <span v-for="(item, index) in fileList" class="cc-file" :key="index">
      <span class="cc-file-item" :class="[{'is-disabled': inputDisabled}]">
        <span class="cc-file-name" :title="item.name">
          <span style="cursor: pointer" v-if="isKnowFile(item)">
            <span @click="showFile(item)">{{item.name}}</span>
          </span>
          <span style="cursor: pointer" v-else-if="isImage(item)">
            <span @click="showImage(item)">{{item.name}}</span>
          </span>
          <span v-else><span>{{item.name}}</span></span>
        </span>
        <span class="cc-file-button">
          <cc-icon
            v-if="item.status === 1"
            style="color: #67C23A;font-size: 16px"
            iconId="018dcab3d3dfd6e82393"
            class="spinner cc-file-upload"
            title="上传中..."
          />
          <cc-icon
            v-if="item.status === 2"
            class="cc-file-download"
            style="color: #409EFF;font-size: 16px"
            iconId="018dc9c3efed1f464d38"
            title="下载"
            @click="downloadFile(item)"
          />
          <cc-icon
            v-if="item.status === 2"
            class="cc-file-delete"
            style="color: #F56C6C;font-size: 16px"
            iconId="018dc9c3efd3a0502886"
            title="删除"
            @click="deleteFile(item)"
          />
        </span>
      </span>
    </span>

    <el-dialog
      :title="dialogTitle"
      v-model="dialogVisible"
      class="no-padding"
      append-to-body
      destroy-on-close
      draggable
      fullscreen
    >
      <vue-office-docx v-if="dialogFileType === 'word'" class="docx" :src="dialogUrl" />
      <vue-office-excel v-if="dialogFileType === 'excel'" :src="dialogUrl" />
    </el-dialog>
  </div>
</template>

<script setup>
import { onMounted, ref, inject, getCurrentInstance, nextTick } from 'vue';
import api from '@/http/api';
import tool from '@/utils/tool';
import loading from '@/utils/loading';
import { ElMessage, ElMessageBox, useDisabled, useFormItem } from 'element-plus';
import '@vue-office/docx/lib/index.css'
import '@vue-office/excel/lib/index.css'

import VueOfficeDocx from '@vue-office/docx'
import VueOfficeExcel from '@vue-office/excel'
import EventHandler from "@/visual/js/event";
import visual from "@/visual/js/visual";

const props = defineProps({
  node: Object
});

const initializing = ref(true);
const pageData = inject("pageData", ref({}));
const uploadCnt = ref(0);
const affixId = ref('');
const limitSize = ref(100);
const fileList = ref([]);
const downloading = ref(false);
const baseImageUrl = ref(import.meta.env.VITE_IMAGE_PATH);
const fileUrl = ref(import.meta.env.VITE_API_PATH + '/file/file/');
const showViewer = ref(false);
const imageUrl = ref('');
const inputDisabled = useDisabled();
const formItem = useFormItem();

const dialogTitle = ref('');
const dialogVisible = ref(false);
const dialogFileType = ref('');
const dialogUrl = ref('');
const currNode = ref(props.node);
const eventHandler = new EventHandler(
  inject('eventHandler', Function, true),
  getCurrentInstance(),
  currNode.value
);

const init = async(styleId) => {
  initializing.value = true;
  visual.initStyle(currNode.value, styleId);
  limitSize.value = currNode.value.currCompStyle['limitSize'] || 100;
  await nextTick(() => initializing.value = false);
};

const loadValue = async() => {
  const dataList = (await visual.loadData(currNode.value.compData, eventHandler, getData(), currNode.value)).data || [];
  pageData.value[currNode.value.name] = dataList && dataList.length > 0 && dataList[0]['内容'] || '';
  loadDataList();
};

const isImage = (file) => {
  return file.name.toLowerCase().endsWith('.png')
    || file.name.toLowerCase().endsWith('.jpeg')
    || file.name.toLowerCase().endsWith('.jpg')
    || file.name.toLowerCase().endsWith('.bmp')
    || file.name.toLowerCase().endsWith('.gif')
};

const showImage = (file) => {
  imageUrl.value = '';
  if (file && file.id) {
    imageUrl.value = baseImageUrl.value + file.id;
    showViewer.value = true;
  }
};

const handleUpload = (file) => {
  return new Promise((resolve, reject) => {
    api.upload({'file': file.file, 'affixId': affixId.value}).then((res) => {
      uploadCnt.value--;

      let filters = fileList.value.filter(item => item.name === res.data.trueName && item.status === 1);
      if (filters.length > 0) {
        filters[0].id = res.data.id;
        filters[0].status = 2;
      }
      resolve();
    }).catch(() => {
      uploadCnt.value--;
      reject();
    });
  })
};

const handleBeforeUpload = (file) => {
  if (affixId.value == null || affixId.value === '') {
    affixId.value = tool.uuid();
    pageData.value[currNode.value.name] = affixId.value;
    handleChange();
  }

  let isLt = file.size / 1024 / 1024 < limitSize.value;
  if (!isLt) {
    ElMessage.error(`上传文件大小不能超过 ${limitSize.value} MB!`);
  } else {
    fileList.value.push({name: file.name, status: 1});
    uploadCnt.value++;
  }

  return isLt;
};

const downloadFile = (file) => {
  api.downloadFileLocal(file.id);
};

const downloadPack = () => {
  if (downloading.value) return;

  downloading.value = true;
  if (affixId.value == null || affixId.value === '') {
    ElMessage.error("暂无附件！");
  }

  api.downloadAffixLocal(affixId.value)
    .then(() => downloading.value = false)
    .catch(() => downloading.value = false);
};

const deleteFile = (file) => {
  ElMessageBox.confirm('请确认是否删除此文件【' + file.name + '】？', '提示', {type: 'warning'}).then(() => {
    api.deleteAffix(file.id).then(() => {
      fileList.value = fileList.value.filter(item => item.id !== file.id)
      if(fileList.value.length === 0){
        affixId.value = '';
        pageData.value[currNode.value.name] = affixId.value;
        handleChange();
      }
    });
  }).catch(()=>{});
};

const loadDataList = () => {
  fileList.value = [];
  let id = pageData.value[currNode.value.name] || '';
  if (id) {
    api.queryAffix(id).then((res) => {
      if(res.data.length > 0){
        affixId.value = id;
        for (let i=0;i<res.data.length;i++) {
          fileList.value.push({name: res.data[i].trueName, id: res.data[i].id, status: 2});
        }
      } else {
        affixId.value = '';
      }
    }).catch((res) => {
      ElMessage.error(res.message);
    });
  } else {
    affixId.value = '';
  }
};

const isKnowFile = (file) => {
  return file.name.toLowerCase().endsWith('.pdf')
    || file.name.toLowerCase().endsWith('.ofd')

    || file.name.toLowerCase().endsWith('.doc')
    || file.name.toLowerCase().endsWith('.docx')
    || file.name.toLowerCase().endsWith('.wps')

    || file.name.toLowerCase().endsWith('.ppt')
    || file.name.toLowerCase().endsWith('.pptx')

    || file.name.toLowerCase().endsWith('.xls')
    || file.name.toLowerCase().endsWith('.xlsx')
    || file.name.toLowerCase().endsWith('.et')
};

const showFile = (file) => {
  dialogUrl.value = '';
  if (file.name.toLowerCase().endsWith('.pdf')) {
    loading.showLoading();
    api.download(file.id).then((res) => {
      let blob = new Blob([res.data], {type: 'application/pdf'})
      let href = window.URL.createObjectURL(blob);
      window.open(href, '_blank');

      loading.hideLoading();
    }).catch((res) => {
      ElMessage.error(res.message);
      loading.hideLoading();
    });
  } else if (file.name.toLowerCase().endsWith('.docx')) {
    dialogTitle.value = "文件查看【" + file.name + "】"
    dialogUrl.value = fileUrl.value + file.id;
    dialogFileType.value = "word";
    dialogVisible.value = true;
  } else if (file.name.toLowerCase().endsWith('.xlsx') || file.name.toLowerCase().endsWith('.xls')) {
    dialogTitle.value = "文件查看【" + file.name + "】"
    dialogUrl.value = fileUrl.value + file.id;
    dialogFileType.value = "excel";
    dialogVisible.value = true;
  }
};

const handleChange = () => {
  nextTick(() => {
    if (formItem && formItem.formItem) {
      formItem.formItem.validate('change');
    }
  });
  eventHandler.trigger('变更事件');
};

const getData = () => {
  return {
    inputParam: currNode.value.inputParam,
    value: pageData.value[currNode.value.name]
  };
};

const changeStyle = (styleId) => {
  init(styleId);
};

const refresh = async() => {
  initializing.value = true;
  await loadValue();
  await nextTick(() => initializing.value = false);
};

onMounted(async() => {
  await init();
  await loadValue();
  await eventHandler.trigger('初始化事件');
});

defineExpose({ getData, changeStyle, refresh });
</script>

<style scoped>
.cc-affix {
  text-align: left;
  margin-bottom: 5px;
  display: flex;
  flex-direction: row;
}
.cc-file {
  width: 100%;
  line-height: 25px;
  display: flex;
  flex-direction: row;
}
.cc-file-item {
  width: 1px;
  flex-grow: 1;
  display: flex;
  flex-direction: row;
  align-items: center;
}
.cc-file-name {
  overflow: hidden;
  min-width: 0;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.cc-file-name > div {
  margin-right: 8px;
}

.cc-file-name > div > div {
  display: flex;
  height: 18px;
  align-items: center;
  text-overflow: ellipsis;
  white-space: nowrap;
  overflow: hidden;
}
.cc-file-upload {
  font-size: 18px;
  margin-left: 5px;
}
.cc-file-button {
  white-space: nowrap;
  padding-right: 8px;
  display: flex;
  justify-content: center;
}
.cc-file-download, .cc-file-delete {
  font-size: 18px;
  cursor: pointer;
  margin-left: 8px;
  width: 25px;
}
.cc-file-download:hover, .cc-file-delete:hover {
  color: #409EFF;
}
.cc-file-item[class~=is-disabled] .cc-file-delete {
  display: none;
}
.pack-button:hover {
  background: #66b1ff;
  border-color: #66b1ff;
  color: #FFF;
}
.pack-button:focus {
  color: #409EFF;
  border-color: #c6e2ff;
  background-color: #ecf5ff;
}
.pack-button {
  padding: 9px 15px;
  font-size: 14px;
  border-radius: 4px;
  color: #FFF;
  background-color: #409EFF;
  border-color: #409EFF;
  display: inline-block;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  -webkit-appearance: none;
  text-align: center;
  box-sizing: border-box;
  outline: 0;
  margin: 0 0 0 12px;
  transition: .1s;
  font-weight: 500;
}
.docx :deep(.docx) {
  padding: 72pt 89.76pt;
  width: 595.28pt;
}
</style>
